package com.apache.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.apache.client.UctCoreClient;
import com.apache.exception.BusinessException;
import com.apache.gateway.config.FilterConfiguration;
import com.apache.gateway.config.GatewayServerHttpRequest;
import com.apache.gateway.config.JedisUtil;
import com.apache.gateway.config.Response;
import com.apache.jwt.Claims;
import com.apache.jwt.PostHttps;
import com.apache.oscache.OsCacheManager;
import com.apache.passport.common.PassportHelper;
import com.apache.passport.common.XmlWhiteUtils;
import com.apache.passport.jwt.JwtUtil;
import com.apache.tools.*;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.PBOSSOTools;
import com.apache.uct.common.ToolsUtil;
import com.google.common.collect.Maps;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.LongAdder;

import reactor.core.publisher.Mono;

/**
 * @description: 统一验证过滤器
 * @author: Hou Dayu
 * @date: Created in 2021/2/2
 */
@Component
public class AuthFilter implements GlobalFilter {

    private Logger logger = LoggerFactory.getLogger("gateway-logs");
    private static Map<String, Map<String,LongAdder>> hystrixs = Maps.newConcurrentMap();//熔断条件存储器

    @Autowired
    private JedisUtil jedisUtil;
    private List<String> fileSuffixs = Arrays.asList("js,css,png,jpg,gif,bmp,swf,fla,ico".split(","));

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long startTime = System.currentTimeMillis();
        ServerHttpRequest request = exchange.getRequest();
        String uri = request.getURI().toString();//获取uri信息
        String suffix = parseUrlSuffix(uri);//获取后缀名,过滤 如果存在后缀为图片,css,js等格式,直接跳过,不拦截
        if ((StrUtil.isNotNull(suffix) && fileSuffixs.contains(suffix.toLowerCase())) ||
                (uri.startsWith("/uniteAuth/randCode") || uri.indexOf("/images/") !=-1 || uri.indexOf("/js/") !=-1
                        || uri.startsWith("/fallback") || uri.indexOf("/common/") !=-1 )) {
            return chain.filter(exchange);
        }
        String traceId = UUIDUtil.getPrimaryKey();
        GatewayServerHttpRequest requestDecorator = new GatewayServerHttpRequest(request);
        requestDecorator.setHeaders("traceId",traceId);
        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);//获取当前路由信息
        JSONObject jsonRoute = getGatewayRoute(route);//获取当前路由信息
        String cookieName = StrUtil.doNull(ConfigUtil.getInstance().getValueByKey("cookieName"), "apache_");
        String tokenId = StrUtil.doNull(requestDecorator.getCookies(cookieName),request.getQueryParams().getFirst("tokenId"));
        if(StrUtil.isNotNull(tokenId)) {//将tokenId写入header
            requestDecorator.setHeaders("zuulucsso", requestDecorator.getCookies("_uc.sso"));
            requestDecorator.setHeaders("zuultokenid", tokenId);
            requestDecorator.setHeaders("gateway-type", "gateway");
        }
        String guuId = requestDecorator.getCookies("__guuid");
        if(StrUtil.isNotNull(guuId)) {//登录验证码
            String randCode = jedisUtil.getCahceInfo(guuId);
            requestDecorator.setHeaders("rand-code", randCode);
        }
        //sso服务直接跳过,"/res/login,/error.action,/errorPage
        String reqConPath = jsonRoute.getString("path").split("/\\*\\*")[0];
        if ("SSO-SERVER".equalsIgnoreCase(route.getId()) || uri.startsWith(reqConPath+"/res/login") || uri.startsWith(reqConPath+"/error.action")
                || uri.startsWith(reqConPath+"/api/login") || uri.startsWith(reqConPath+"/errorPage") || uri.startsWith(reqConPath+"/error") || uri.startsWith(reqConPath+"/cset")) {
            return chain.filter(exchange.mutate().request(requestDecorator).build());
        }
        String ip = FilterConfiguration.getIpAddress(request);
        StringBuilder normalMsg = new StringBuilder();
        normalMsg.append("traceId = "+traceId).append("; requestUrl = "+request.getURI().toString());
        normalMsg.append("; requestIp = "+ ip).append("; exeSys = gateway; requestTime = "+ DateUtils.Now.fmt_yyyyMMdd_HHmmss());
        boolean ifLogs = "1".equals(jsonRoute.getString("ifLog"));//是否开启日志输出
        JSONObject zuulBlack = jedisUtil.getRoute("black.white",ip);
        if("0".equals(zuulBlack.getString("infoType"))){//黑名单
            Response json = new Response("100", "请求失败", "您已被拉入黑名单，此次访问已被禁止");
            return writeWith(exchange, json, startTime, ifLogs,normalMsg.toString());
        }
        if ("1".equals(jsonRoute.getString("ifHystrix"))) {//开启熔断
            long dd = Double.valueOf(StrUtil.doNull(jsonRoute.getString("hystrixContent"), "1000")).longValue();
            String date = DateUtils.Now.fmt_yyyyMMdd();
            if (!hystrixs.containsKey(uri)) {
                Map<String, LongAdder> limit = new HashMap();
                limit.put(date, new LongAdder());
                hystrixs.put(uri, limit);
            }
            Map<String, LongAdder> limit = hystrixs.get(uri);
            boolean tryAcquire = true;
            if (limit.containsKey(date)) {
                LongAdder lad = limit.get(date);
                if (dd >= lad.sum()) {
                    lad.increment();
                    tryAcquire = false;
                }
            } else {
                limit.clear();
                limit.put(date, new LongAdder());
                tryAcquire = false;
            }
            if (tryAcquire) {//达到熔断条件
                Response json = new Response("200", "请求成功", "系统对此功能已暂停服务");
                return writeWith(exchange, json, startTime, ifLogs,normalMsg.toString());
            }
        }
        String loginUrl = authPath(exchange,requestDecorator,jsonRoute,tokenId);
        if(StrUtil.isNotNull(loginUrl)){//跳转登录页
            ServerHttpResponse response = exchange.getResponse();
            response.getHeaders().set(HttpHeaders.LOCATION, loginUrl);
            response.setStatusCode(HttpStatus.FOUND);
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return response.setComplete();
        }
        if(ifLogs){
            return chain.filter(exchange.mutate().request(requestDecorator).build()).then(Mono.fromRunnable(() -> {
                normalMsg.append("; infoType = info; total = " + (System.currentTimeMillis() - startTime));
                logger.warn(normalMsg.toString());
            }));
        }
        return chain.filter(exchange.mutate().request(requestDecorator).build());
    }

    private String authPath(ServerWebExchange exchange, GatewayServerHttpRequest request, JSONObject route,String tokenId){
        String pkt = request.getQueryParams().getFirst("tokenId");
        if ("undefined".equalsIgnoreCase(pkt))
            pkt = "";
        tokenId = StrUtil.doNull(tokenId,pkt);
        String serviceId = route.getString("serviceId");
        String env_path = route.getString("path");
        String sysEname = "";
        String path = env_path.split("/\\*\\*")[0];
        if(StrUtil.isNotNull(serviceId)){
            sysEname = serviceId.split("-")[0].toLowerCase();
        }

        boolean tokenMark = true;
        String uri = request.getPath().toString();
        if (!uri.equals(path + "/logout") && !uri.equals(path + "/cset")) {
            String code = request.getQueryParams().getFirst("code");
            //是否用jwt验证
            if ("T".equals(ToolsUtil.getInstance().getValueByKey("if_jwt_check"))) {
                if (StrUtil.isNotNull(code)) {
                    tokenId = getAccessToken(code, request);
                }
            }
        }
        if (StrUtil.isNull(tokenId)) {
            tokenMark = false;
        }
        String loginUrl = null;
        String scheme = request.getURI().getScheme();
        String serverName = request.getURI().getHost();
        int severPort = request.getURI().getPort();
        String config_custom_login = route.getString("loginUrl");//配置文件自定义登录地址
        if(StrUtil.isNull(config_custom_login)){
            try {
                loginUrl = getLonginUrl(request, tokenId,"sso",sysEname);
            } catch (UnsupportedEncodingException e) {
            }
        } else {
            StringBuilder csetUrl = new StringBuilder(scheme + "://").append(serverName);
            csetUrl.append(":" + (80==severPort ? "" : severPort+""));
            loginUrl = csetUrl.toString() + config_custom_login;//自定义登录页面
        }
        if(path.equals(request.getPath().value())){
            if(tokenMark){
                StringBuilder csetUrl = new StringBuilder(scheme + "://").append(serverName);
                csetUrl.append(":" + (80==severPort ? "" : severPort+""));
                return csetUrl.toString()+path+"/";
            }
            return loginUrl;
        }
        if (uri.equals(path + "/logout")) {
            return doLogout(request, tokenId, loginUrl);
        } else if (uri.equals(path + "/cset")) {
            return setCookie(request);//设置cookie
        } else {
            //checkLogin(request,tokenId);
            boolean mark = whitePathFiter(uri.replace(path,""), request,sysEname);//白名单处理
            if(!mark){
                if (tokenMark) {
                    LoginUser loginUser = OsCacheManager.getInstance().getLoginUser(tokenId);
                    if (null == loginUser && StrUtil.isNotNull(tokenId)) {
                        loginUser = UctCoreClient.getLoginUserFromUserCenterSso("", tokenId);
                        OsCacheManager.getInstance().putLoginUser(tokenId, loginUser);
                    }
                    if (null != loginUser) {
                        String userType = loginUser.getUserType();
                        //只有管理员可以进/admin,customer只能进web/user
                        if (uri.indexOf("/admin") > -1 && !"manager".equalsIgnoreCase(userType)
                                || uri.indexOf("/web/user") > -1 && !"customer".equalsIgnoreCase(userType)) {
                            throw new BusinessException("系统拒绝访问，您的操作权限受限");
                        }
                    }
                } else {
                    if (!StrUtil.isNull(tokenId)) {
                        clearCookie(tokenId, request, "/");
                    }
                    logger.info("sysEname->"+sysEname+",uri="+uri+" -> whitePathFiter = "+mark);
                    if (!mark) {
                        logger.info(sysEname+".redirect.loginUrl->"+loginUrl);
                        return loginUrl;
                    }
                }
            }
        }
        return null;
    }

    /**
     * description:  获取accessToken
     */
    private String getAccessToken(String code, GatewayServerHttpRequest request) {
        String tokenId = "";
        String login_url = ToolsUtil.getInstance().getValueByKey("uct_server");
        try {
            String clientEname = ToolsUtil.getInstance().getValueByKey("sysEname");
            String url = login_url + "passport/outside/access_token";
            NameValuePair[] parasInput = new NameValuePair[3];
            parasInput[0] = new BasicNameValuePair("code", code);
            parasInput[1] = new BasicNameValuePair("clientid", clientEname);
            parasInput[2] = new BasicNameValuePair("grant_type", "authorization_code");
            String jsonStr = "";
            if (url.startsWith("https:")) {
                jsonStr = PostHttps.newInstance().getHttpsForStl(url, parasInput, "GET");
            } else {
                jsonStr = PostHttps.newInstance().getHttp(url, parasInput, "GET");
            }
            if (StrUtil.isNull(jsonStr))
                return "";
            net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(jsonStr);
            if ("200".equals(json.get("state"))) {
                String cookieName = ToolsUtil.getInstance().getValueByKey("cookieName");
                String idToken = json.getString("id_token");
                Claims claims = JwtUtil.newInstance().uniParseJWT(idToken);
                if (null == claims) {
                    return "";
                }
                String aud = claims.getAudience();
                if (!aud.contains(clientEname))
                    return "";
                tokenId = "uni_" + code;
                net.sf.json.JSONObject ujson = net.sf.json.JSONObject.fromObject(claims.get("u_info"));
                String userEname = ujson.getString("userEname");
                LoginUser loginUser = PBOSSOTools.getLoginUserFromUserCenter(userEname, tokenId);
                OsCacheManager.getInstance().putLoginUser(tokenId, loginUser);
                OsCacheManager.getInstance().putSessionTokenId(tokenId+"_sessioin", idToken);
                request.setCookies(cookieName,"uni_" + code);
                request.setCookies("_uc.sso",userEname);
            }
        } catch (Exception e) {
        }
        return tokenId;
    }

    /**
     * description: 白名单验证
     */
    protected boolean whitePathFiter(String uri, GatewayServerHttpRequest req, String sysCode) {
        //初始化白名单
        sysCode = StrUtil.isNotNull(sysCode) ? sysCode : "";
        String fileName = (StrUtil.isNull(sysCode)? "" : sysCode+"_") + "white.xml";
        //boolean cacheFlag = XmlWhiteUtils.getInstance().getConfigForCache("", fileName);
		/*if(!cacheFlag){
			sysCode = "";
		}*/
        Map<String, ArrayList<String>> whiteMap = new HashMap();
        logger.info("uri->"+uri+" whitePathFiter.sysCode->"+sysCode+" file ["+fileName+"]");
        XmlWhiteUtils.getInstance().deWhiteXml(whiteMap, sysCode);
        ArrayList<String> whiteUrl2 = whiteMap.get("whiteUrl");
        ArrayList<String> whiteParadigm = whiteMap.get("whiteParadigm");
        //url白名单
        if (whiteUrl2.contains(uri)) {
            return true;
        } else {
            int wp = whiteParadigm.size();
            if (uri.length() > 1) {//主要是/造成,如guo/后面有内容,则进入以下方法
                for (int i = 0; i < wp; i++) {
                    if ((whiteParadigm.get(i)).contains("*")) {
                        String wdir = (whiteParadigm.get(i)).replace("*", "");
                        int s = uri.indexOf(wdir);
                        if (s == 0) {
                            return true;
                        }
                    } else {
                        if (!"".equals(whiteParadigm.get(i))) {
                            int s = uri.indexOf(whiteParadigm.get(i));
                            if (s == 0) {
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * description:  用户退出操作
     */
    private String doLogout(GatewayServerHttpRequest req, String tokenCookie,String loginUrl) {
        if (StrUtil.isNull(tokenCookie)) {
            clearCookie("", req,  "/");
        }else {
            clearCookie(tokenCookie, req,"/");
        }
        return "";
    }

    /**
     * description:  设置本地cookie
     */
    private String setCookie(GatewayServerHttpRequest req) {
        String token = req.getQueryParams().getFirst("ticket");
        String ucsso = req.getQueryParams().getFirst("ucsso");
        String gotoURL = req.getQueryParams().getFirst("go");
        String cookieName = ToolsUtil.getInstance().getValueByKey("cookieName");
        if (StrUtil.isNotNull(gotoURL)) {
            gotoURL = gotoURL.replaceAll("\\|", "&");
            if (gotoURL.indexOf("token_code") == -1 && StrUtil.isNotNull(token) && StrUtil
                    .isNotNull(ucsso)) {
                req.setCookies(cookieName,token);
                req.setCookies("_uc.sso", ucsso);
                if (gotoURL.indexOf("?tokenId=") != -1) {
                    gotoURL = gotoURL.replaceAll("tokenId=" + token + "&", "");
                } else {
                    gotoURL = gotoURL.replaceAll("&tokenId=" + token, "");
                }
            }
            return gotoURL;
        }
        return "";
    }

    /**
     * description:  清空本地cookie
     */
    private void clearCookie(String tokenId, GatewayServerHttpRequest request, String path) {
        request.delCookieAll();
        OsCacheManager.getInstance().removeLoginUser(tokenId+"_sessioin");
        OsCacheManager.getInstance().removeLoginUser(tokenId);
    }

    /**
     * 判断用户是否已登录
     */
    private void checkLogin(GatewayServerHttpRequest request,String tokenId){
        String requestURI = request.getURI().toString();
        if(requestURI.indexOf("/res/login")>-1 || requestURI.indexOf("/api/login")>-1){
            boolean flag = false;
            if(StrUtil.isNull(tokenId)){
                LoginUser loginUser = OsCacheManager.getInstance().getLoginUser(tokenId);
                if(null!=loginUser){
                    flag=true;
                }
            } else {
                flag=true;
            }
            if(flag){
                throw new BusinessException("2011");
            }
        }

    }

    private String getLonginUrl(GatewayServerHttpRequest request, String tokenId,String defaultSso,String sysEname) throws UnsupportedEncodingException {
        String loginUrl = "";
        String customLogin = ToolsUtil.getInstance().getValueByKey("custom_login");
        if (StrUtil.isNotNull(tokenId) && tokenId.indexOf("uni_") > -1) {
            loginUrl = doSsoFiltersForEid(request, tokenId, "",sysEname);
        } else if ("sso".equals(defaultSso)) {
            loginUrl = doSsoFilters(request, tokenId, "",sysEname);
        } else if ("eid".equals(defaultSso)) {
            loginUrl = doSsoFiltersForEid(request, tokenId, "",sysEname);
        } else {
            loginUrl = sysEname + StrUtil.doNull(customLogin, "/login.jsp");
        }
        return loginUrl;
    }

    /**
     * description: sso参数组装
     */
    private String doSsoFilters(GatewayServerHttpRequest request,
                                String tokenId, String pkt,String sysPath) throws UnsupportedEncodingException {
        String path = request.getPath().toString();
        //要跳转到哪个url
        String gotoURL = request.getQueryParams().getFirst("go");
        String csetUrl = request.getHeader("realServerName");

        if (gotoURL == null) {
            gotoURL = request.getURI().toString();
        }
        String reqParams = "";//customLogin
/*        if ("T".equals(ToolsUtil.getInstance().getValueByKey("is_url_params"))) {
            reqParams = PassportHelper.getInstance().getReqParams(request, "go");
            reqParams = PassportHelper.getInstance().isNov(reqParams, reqParams, "?" + reqParams);
        }*/
        String login_url = ToolsUtil.getInstance().getValueByKey("uct_server");
        //是否使用统一登录系统登录 T/F
        String login_pass = ToolsUtil.getInstance().getValueByKey("login.pass");
        ArrayList<String> lst = new ArrayList<String>();
        String sha1Rtn = "";
        if (StrUtil.isNull(tokenId) && StrUtil.isNotNull(pkt)) {//客户端调用
            StringBuffer tokenUrl = new StringBuffer();
            lst.add(login_url);
            lst.add(pkt);
            lst.add(gotoURL + reqParams);
            lst.add("apache");
            lst.add(csetUrl);
            Collections.sort(lst);
            sha1Rtn = PassportHelper.getInstance().SHA1(lst);
            if ("T".equals(login_pass)) {
                //如果cookie为空,则跳转到登录页面
                tokenUrl.append(login_url);
                tokenUrl.append("?");
                tokenUrl.append("tokenId=" + pkt);//设置远程cookie
                tokenUrl.append("&go=" + gotoURL + reqParams);
                tokenUrl.append("&ptlang=" + sha1Rtn);
                tokenUrl.append("&cset=" + csetUrl);
            } else {
                tokenUrl.append(login_url);
            }
            return tokenUrl.toString();
        }/////客户端调用结束
        String sysEname = ToolsUtil.getInstance().getValueByKey("sysEname");
        //统一登录系统平台回调参数
        String cset = csetUrl + "/cset";
        lst.add(login_url);
        lst.add(sysEname);
        lst.add(cset);
        if (request.getURI().toString().equals(path + "/logout")) {
            lst.add(gotoURL);
        } else {
            lst.add(gotoURL + reqParams);
        }
        lst.add("apache");
        Collections.sort(lst);
        sha1Rtn = PassportHelper.getInstance().SHA1(lst);

        StringBuffer loginUrl = new StringBuffer();
        if ("T".equals(login_pass)) {
            //如果cookie为空,则跳转到登录页面
            loginUrl.append(login_url);
            loginUrl.append("?");
            loginUrl.append("_client=" + sha1Rtn);
            loginUrl.append("&");
            loginUrl.append("sys=" + sysEname);//系统名称
            loginUrl.append("&");
            loginUrl.append("cset=" + URLEncoder.encode(cset, "UTF-8"));//设置远程cookie
            loginUrl.append("&");
            loginUrl.append("go=" + URLEncoder.encode(gotoURL, "UTF-8") + reqParams);
        } else {
            loginUrl.append(login_url);
        }
        return loginUrl.toString();
    }

    /**
     * description: Eid参数组装
     */
    private String doSsoFiltersForEid(GatewayServerHttpRequest request,
                                      String tokenId, String pkt,String sysPath) throws UnsupportedEncodingException {
        //要跳转到哪个url
        String gotoURL = request.getQueryParams().getFirst("go");
        if (gotoURL == null) {
            gotoURL = request.getURI().toString();
        }
        String reqParams = "";//customLogin
        /*if ("T".equals(ToolsUtil.getInstance().getValueByKey("is_url_params"))) {
            reqParams = PassportHelper.getInstance().getReqParams(request, "go,code");
            reqParams = PassportHelper.getInstance().isNov(reqParams, reqParams, "?" + reqParams);
        }*/
        String login_url = ToolsUtil.getInstance().getValueByKey("uct_server");
        //是否使用统一登录系统登录 T/F
        String login_pass = ToolsUtil.getInstance().getValueByKey("login.pass");
        String sysEname = ToolsUtil.getInstance().getValueByKey("sysEname");
        ArrayList<String> lst = new ArrayList<String>();
        String sha1Rtn = "";
        if (StrUtil.isNull(tokenId) && StrUtil.isNotNull(pkt)) {//客户端调用
            StringBuffer tokenUrl = new StringBuffer();
            lst.add(login_url);
            lst.add("apache");
            Collections.sort(lst);
            sha1Rtn = PassportHelper.getInstance().SHA1(lst);
            if ("T".equals(login_pass)) {
                //如果cookie为空,则跳转到登录页面
                tokenUrl.append(login_url);
                tokenUrl.append("?_client=" + sha1Rtn);
                tokenUrl.append("&tokenId=" + pkt);//设置远程cookie
                tokenUrl.append("&clientid=" + sysEname);//系统名称
                tokenUrl.append("&response_type=" + "code");
                tokenUrl.append("&scope=" + "openid");
                tokenUrl.append("&go=" + gotoURL + reqParams);
            } else {
                tokenUrl.append(login_url);
            }
            return tokenUrl.toString();
        }/////客户端调用结束

        //统一登录系统平台回调参数
        lst.add(login_url);
        lst.add(sysEname);
        lst.add("apache");
        Collections.sort(lst);
        sha1Rtn = PassportHelper.getInstance().SHA1(lst);

        StringBuffer loginUrl = new StringBuffer();
        if ("T".equals(login_pass)) {
            //如果cookie为空,则跳转到登录页面
            loginUrl.append(login_url);
            loginUrl.append("?_client=" + sha1Rtn);
            loginUrl.append("&clientid=" + sysEname);//系统名称
            loginUrl.append("&response_type=" + "code");
            loginUrl.append("&scope=" + "openid");
            loginUrl.append("&go=" + URLEncoder.encode(gotoURL, "UTF-8") + reqParams);
        } else {
            loginUrl.append(login_url);
        }
        return loginUrl.toString();
    }

    private JSONObject getGatewayRoute(Route route){
        String key = route.getId();
        return jedisUtil.getRoute("",key);
    }

    /**
     * 写返回数据
     */
    private Mono<Void> writeWith(ServerWebExchange exchange, Response json, long startTime, boolean isOpenLog,String logMsg){
        ServerHttpResponse response = exchange.getResponse();
        DataBuffer bodyDataBuffer = response.bufferFactory().wrap(JSON.toJSONString(json).getBytes());
        if(isOpenLog) {
            StringBuilder sb = new StringBuilder();
            sb.append(logMsg).append("; infoType = warn");
            sb.append("; total = " + (System.currentTimeMillis() - startTime));
            sb.append("; errorMessage = " + json.getData() + "; level = ERROR");
            logger.warn(sb.toString());
        }
        return response.writeWith(Mono.just(bodyDataBuffer));
    }

    /**
     * description:  支持全部url,webservice
     */
    private String parseUrlSuffix(String url) {
        int lastIndex = 0;
        String rtn = "";
        if (url.length() <= 1) {
            return rtn;
        }
        if (url.contains(".")) {
            lastIndex = url.lastIndexOf('.') + 1;
            return url.substring(lastIndex, url.length());
        }
        if (url.contains("@")) {
            lastIndex = url.lastIndexOf('@') + 1;
            return url.substring(lastIndex, url.length());
        }
        if (url.contains("#")) {
            lastIndex = url.lastIndexOf('#') + 1;
            return url.substring(lastIndex, url.length());
        }
        if (url.contains("?")) {
            lastIndex = url.lastIndexOf('?') + 1;
            return url.substring(lastIndex, url.length());
        }
        if (url.contains("!")) {
            lastIndex = url.lastIndexOf('!') + 1;
            String value = url.substring(lastIndex, url.length());
            if (value.contains(".")) {
                rtn = value.substring(value.indexOf('.'), value.length());
                return rtn;
            }
        }
        return url.substring(lastIndex, url.length());
    }
}
